#include "common.h"

//服务端的主逻辑

int main(){

    //定义一个数组，记录每个孩子的信息，然后初始化进程池
    son_information list[5];
    memset(list, 0, sizeof(list));
    init_process_pool(list, 5);


    //开始建立连接,初始化用于监听的socket
    int socket_fd;
    char *ip = "192.168.119.130"; //服务端，也就是自己的ip
    char *port = "8080";//需要监听的端口
    init_listen_socket(&socket_fd, ip, port);//注意，监听socket_fd是个传入传出参数，用指针形式传入


    //IO多路复用
    //1.要监听是否有新的连接进来
    //2.监听子进程有没有发消息过来
    int epoll_fd = epoll_create(1);
    add_epoll(epoll_fd, socket_fd); //将监听socket添加到epoll中监听
    
    for(int i=0; i<5; i++){
        //将和子进程通信的本地socket添加到监听当中
        add_epoll(epoll_fd, list[i].local_socket);
    }

    //开始监听
    while(1){
        struct epoll_event events[5]; //记录监听内容
        memset(events, 0, sizeof(events));
        int epoll_num = epoll_wait(epoll_fd, events, 5, -1); //查看监听变化

        //遍历，看发生变化的是哪些监听
        for(int i=0; i<epoll_num; i++){
            //获取发生变化的文件描述符
            int fd = events[i].data.fd;
            if(fd == socket_fd){
                //如果是监听socket发生变化，说明有新的链接进来
                //取出和该客户端建立好TCP连接的通信socket
                int net_fd = accept(socket_fd, NULL, NULL);
                //将建立好的通信socket交给子进程，让它为客户服务
                to_son(list, 5, net_fd);
                //父进程不用为他服务，将net_fd在父进程的文件描述符表中的占用删掉
                //但并不会关闭建立好的通信socket
                close(net_fd);
                continue; //处理结束，跳出本次循环
            }
            
            //检查是不是，与某个子进程通信的本地socket，发生了状态变化
            int is_son = -1;    //初始化为-1表示不是和子进程本地通信的socket发生变化
            for(int j=0; j<5; j++){
                //逐一比对，如果符合，那就记录
                if(fd == list[j].local_socket){
                    is_son=j;
                }
            }
            if(is_son!=-1){
                //is_son不为-1，说明通过for循环的比较，确定了是和某个子进程通信的本地socket发生变化
                char buf[50] = {0};
                recv(fd, buf, sizeof(buf), 0);
                list[is_son].status = FREE;
            }

        }//end_for, i 
    }//end,whilei
     
    return 0;
}
